home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / pyxmpp / jabber / disco.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  19KB  |  628 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __revision__ = '$Id: disco.py 666 2006-12-03 15:40:54Z jajcus $'
  5. __docformat__ = 'restructuredtext en'
  6. import warnings
  7. import libxml2
  8. from pyxmpp.xmlextra import common_doc, common_root
  9. from pyxmpp.jid import JID
  10. from pyxmpp import cache
  11. from pyxmpp.utils import to_utf8
  12. from pyxmpp.objects import StanzaPayloadWrapperObject
  13. from pyxmpp.exceptions import ProtocolError
  14. DISCO_NS = 'http://jabber.org/protocol/disco'
  15. DISCO_ITEMS_NS = DISCO_NS + '#items'
  16. DISCO_INFO_NS = DISCO_NS + '#info'
  17.  
  18. class DiscoItem(StanzaPayloadWrapperObject):
  19.     
  20.     def __init__(self, disco, xmlnode_or_jid, node = None, name = None, action = None):
  21.         self.disco = disco
  22.         if isinstance(xmlnode_or_jid, JID):
  23.             if disco:
  24.                 self.xmlnode = disco.xmlnode.newChild(None, 'item', None)
  25.             else:
  26.                 self.xmlnode = common_root.newChild(None, 'item', None)
  27.                 ns = self.xmlnode.newNs(DISCO_ITEMS_NS, None)
  28.                 self.xmlnode.setNs(ns)
  29.             self.set_jid(xmlnode_or_jid)
  30.             self.set_name(name)
  31.             self.set_node(node)
  32.             self.set_action(action)
  33.         elif disco is None:
  34.             self.xmlnode = xmlnode_or_jid.copyNode(1)
  35.         else:
  36.             self.xmlnode = xmlnode_or_jid
  37.         if name:
  38.             self.set_name(name)
  39.         
  40.         if node:
  41.             self.set_node(node)
  42.         
  43.         if action:
  44.             self.set_action(action)
  45.         
  46.         self.xpath_ctxt = common_doc.xpathNewContext()
  47.         self.xpath_ctxt.setContextNode(self.xmlnode)
  48.         self.xpath_ctxt.xpathRegisterNs('d', DISCO_ITEMS_NS)
  49.  
  50.     
  51.     def __del__(self):
  52.         if self.disco is None:
  53.             if self.xmlnode:
  54.                 self.xmlnode.unlinkNode()
  55.                 self.xmlnode.freeNode()
  56.                 self.xmlnode = None
  57.             
  58.         
  59.         if self.xpath_ctxt:
  60.             self.xpath_ctxt.xpathFreeContext()
  61.         
  62.  
  63.     
  64.     def __str__(self):
  65.         return self.xmlnode.serialize()
  66.  
  67.     
  68.     def remove(self):
  69.         if self.disco is None:
  70.             return None
  71.         
  72.         self.xmlnode.unlinkNode()
  73.         oldns = self.xmlnode.ns()
  74.         ns = self.xmlnode.newNs(oldns.getContent(), None)
  75.         self.xmlnode.replaceNs(oldns, ns)
  76.         common_root.addChild(self.xmlnode())
  77.         self.disco = None
  78.  
  79.     
  80.     def get_name(self):
  81.         name = self.xmlnode.prop('name')
  82.         if name is None:
  83.             return None
  84.         
  85.         return name.decode('utf-8')
  86.  
  87.     
  88.     def set_name(self, name):
  89.         if name is None:
  90.             if self.xmlnode.hasProp('name'):
  91.                 self.xmlnode.unsetProp('name')
  92.             
  93.             return None
  94.         
  95.         name = unicode(name)
  96.         self.xmlnode.setProp('name', name.encode('utf-8'))
  97.  
  98.     name = property(get_name, set_name)
  99.     
  100.     def get_node(self):
  101.         node = self.xmlnode.prop('node')
  102.         if node is None:
  103.             return None
  104.         
  105.         return node.decode('utf-8')
  106.  
  107.     
  108.     def set_node(self, node):
  109.         if node is None:
  110.             if self.xmlnode.hasProp('node'):
  111.                 self.xmlnode.unsetProp('node')
  112.             
  113.             return None
  114.         
  115.         node = unicode(node)
  116.         self.xmlnode.setProp('node', node.encode('utf-8'))
  117.  
  118.     node = property(get_node, set_node)
  119.     
  120.     def get_action(self):
  121.         action = self.xmlnode.prop('action')
  122.         if action is None:
  123.             return None
  124.         
  125.         return action.decode('utf-8')
  126.  
  127.     
  128.     def set_action(self, action):
  129.         if action is None:
  130.             if self.xmlnode.hasProp('action'):
  131.                 self.xmlnode.unsetProp('action')
  132.             
  133.             return None
  134.         
  135.         if action not in ('remove', 'update'):
  136.             raise ValueError, "Action must be 'update' or 'remove'"
  137.         
  138.         action = unicode(action)
  139.         self.xmlnode.setProp('action', action.encode('utf-8'))
  140.  
  141.     action = property(get_action, set_action)
  142.     
  143.     def get_jid(self):
  144.         jid = self.xmlnode.prop('jid')
  145.         return JID(jid.decode('utf-8'))
  146.  
  147.     
  148.     def set_jid(self, jid):
  149.         self.xmlnode.setProp('jid', jid.as_unicode().encode('utf-8'))
  150.  
  151.     jid = property(get_jid, set_jid)
  152.  
  153.  
  154. class DiscoIdentity(StanzaPayloadWrapperObject):
  155.     
  156.     def __init__(self, disco, xmlnode_or_name, item_category = None, item_type = None, replace = False):
  157.         self.disco = disco
  158.         if disco and replace:
  159.             old = disco.xpath_ctxt.xpathEval('d:identity')
  160.             if old:
  161.                 for n in old:
  162.                     n.unlinkNode()
  163.                     n.freeNode()
  164.                 
  165.             
  166.         
  167.         if isinstance(xmlnode_or_name, libxml2.xmlNode):
  168.             if disco is None:
  169.                 self.xmlnode = xmlnode_or_name.copyNode(1)
  170.             else:
  171.                 self.xmlnode = xmlnode_or_name
  172.         elif not item_category:
  173.             raise ValueError, 'DiscoInfo requires category'
  174.         elif not item_type:
  175.             raise ValueError, 'DiscoInfo requires type'
  176.         elif disco:
  177.             self.xmlnode = disco.xmlnode.newChild(None, 'identity', None)
  178.         else:
  179.             self.xmlnode = common_root.newChild(None, 'identity', None)
  180.             ns = self.xmlnode.newNs(DISCO_INFO_NS, None)
  181.             self.xmlnode.setNs(ns)
  182.         self.set_name(xmlnode_or_name)
  183.         self.set_category(item_category)
  184.         self.set_type(item_type)
  185.         self.xpath_ctxt = common_doc.xpathNewContext()
  186.         self.xpath_ctxt.setContextNode(self.xmlnode)
  187.         self.xpath_ctxt.xpathRegisterNs('d', DISCO_INFO_NS)
  188.  
  189.     
  190.     def __del__(self):
  191.         if self.disco is None:
  192.             if self.xmlnode:
  193.                 self.xmlnode.unlinkNode()
  194.                 self.xmlnode.freeNode()
  195.                 self.xmlnode = None
  196.             
  197.         
  198.         if self.xpath_ctxt:
  199.             self.xpath_ctxt.xpathFreeContext()
  200.         
  201.  
  202.     
  203.     def __str__(self):
  204.         return self.xmlnode.serialize()
  205.  
  206.     
  207.     def remove(self):
  208.         if self.disco is None:
  209.             return None
  210.         
  211.         self.xmlnode.unlinkNode()
  212.         oldns = self.xmlnode.ns()
  213.         ns = self.xmlnode.newNs(oldns.getContent(), None)
  214.         self.xmlnode.replaceNs(oldns, ns)
  215.         common_root.addChild(self.xmlnode())
  216.         self.disco = None
  217.  
  218.     
  219.     def get_name(self):
  220.         var = self.xmlnode.prop('name')
  221.         if not var:
  222.             var = ''
  223.         
  224.         return var.decode('utf-8')
  225.  
  226.     
  227.     def set_name(self, name):
  228.         if not name:
  229.             raise ValueError, 'name is required in DiscoIdentity'
  230.         
  231.         name = unicode(name)
  232.         self.xmlnode.setProp('name', name.encode('utf-8'))
  233.  
  234.     name = property(get_name, set_name)
  235.     
  236.     def get_category(self):
  237.         var = self.xmlnode.prop('category')
  238.         if not var:
  239.             var = '?'
  240.         
  241.         return var.decode('utf-8')
  242.  
  243.     
  244.     def set_category(self, category):
  245.         if not category:
  246.             raise ValueError, 'Category is required in DiscoIdentity'
  247.         
  248.         category = unicode(category)
  249.         self.xmlnode.setProp('category', category.encode('utf-8'))
  250.  
  251.     category = property(get_category, set_category)
  252.     
  253.     def get_type(self):
  254.         item_type = self.xmlnode.prop('type')
  255.         if not item_type:
  256.             item_type = '?'
  257.         
  258.         return item_type.decode('utf-8')
  259.  
  260.     
  261.     def set_type(self, item_type):
  262.         if not item_type:
  263.             raise ValueError, 'Type is required in DiscoIdentity'
  264.         
  265.         item_type = unicode(item_type)
  266.         self.xmlnode.setProp('type', item_type.encode('utf-8'))
  267.  
  268.     type = property(get_type, set_type)
  269.  
  270.  
  271. class DiscoItems(StanzaPayloadWrapperObject):
  272.     
  273.     def __init__(self, xmlnode_or_node = None):
  274.         self.xmlnode = None
  275.         self.xpath_ctxt = None
  276.         if isinstance(xmlnode_or_node, libxml2.xmlNode):
  277.             ns = xmlnode_or_node.ns()
  278.             if ns.getContent() != DISCO_ITEMS_NS:
  279.                 raise ValueError, 'Bad disco-items namespace'
  280.             
  281.             self.xmlnode = xmlnode_or_node.docCopyNode(common_doc, 1)
  282.             common_root.addChild(self.xmlnode)
  283.             self.ns = self.xmlnode.ns()
  284.         else:
  285.             self.xmlnode = common_root.newChild(None, 'query', None)
  286.             self.ns = self.xmlnode.newNs(DISCO_ITEMS_NS, None)
  287.             self.xmlnode.setNs(self.ns)
  288.             self.set_node(xmlnode_or_node)
  289.         self.xpath_ctxt = common_doc.xpathNewContext()
  290.         self.xpath_ctxt.setContextNode(self.xmlnode)
  291.         self.xpath_ctxt.xpathRegisterNs('d', DISCO_ITEMS_NS)
  292.  
  293.     
  294.     def __del__(self):
  295.         if self.xmlnode:
  296.             self.xmlnode.unlinkNode()
  297.             self.xmlnode.freeNode()
  298.             self.xmlnode = None
  299.         
  300.         if self.xpath_ctxt:
  301.             self.xpath_ctxt.xpathFreeContext()
  302.             self.xpath_ctxt = None
  303.         
  304.  
  305.     
  306.     def get_node(self):
  307.         node = self.xmlnode.prop('node')
  308.         if not node:
  309.             return None
  310.         
  311.         return node.decode('utf-8')
  312.  
  313.     
  314.     def set_node(self, node):
  315.         if node is None:
  316.             if self.xmlnode.hasProp('node'):
  317.                 self.xmlnode.unsetProp('node')
  318.             
  319.             return None
  320.         
  321.         node = unicode(node)
  322.         self.xmlnode.setProp('node', node.encode('utf-8'))
  323.  
  324.     node = property(get_node, set_node)
  325.     
  326.     def get_items(self):
  327.         ret = []
  328.         l = self.xpath_ctxt.xpathEval('d:item')
  329.         if l is not None:
  330.             for i in l:
  331.                 ret.append(DiscoItem(self, i))
  332.             
  333.         
  334.         return ret
  335.  
  336.     
  337.     def set_items(self, item_list):
  338.         for item in self.items:
  339.             item.remove()
  340.         
  341.         for item in item_list:
  342.             
  343.             try:
  344.                 self.add_item(item.jid, item.node, item.name, item.action)
  345.             continue
  346.             except AttributeError:
  347.                 self.add_item(*item)
  348.                 continue
  349.             
  350.  
  351.         
  352.  
  353.     items = property(get_items, set_items, doc = 'List of `DiscoItems`')
  354.     
  355.     def invalidate_items(self):
  356.         warnings.warn('DiscoItems.invalidate_items() is deprecated and not needed any more.', DeprecationWarning, stacklevel = 1)
  357.  
  358.     
  359.     def add_item(self, jid, node = None, name = None, action = None):
  360.         return DiscoItem(self, jid, node, name, action)
  361.  
  362.     
  363.     def has_item(self, jid, node = None):
  364.         l = self.xpath_ctxt.xpathEval('d:item')
  365.         if l is None:
  366.             return False
  367.         
  368.         for it in l:
  369.             di = DiscoItem(self, it)
  370.             if di.jid == jid and di.node == node:
  371.                 return True
  372.                 continue
  373.         
  374.         return False
  375.  
  376.  
  377.  
  378. class DiscoInfo(StanzaPayloadWrapperObject):
  379.     
  380.     def __init__(self, xmlnode_or_node = None, parent = None, doc = None):
  381.         self.xmlnode = None
  382.         self.xpath_ctxt = None
  383.         if not doc:
  384.             doc = common_doc
  385.         
  386.         if not parent:
  387.             parent = common_root
  388.         
  389.         if isinstance(xmlnode_or_node, libxml2.xmlNode):
  390.             ns = xmlnode_or_node.ns()
  391.             if ns.getContent() != DISCO_INFO_NS:
  392.                 raise ValueError, 'Bad disco-info namespace'
  393.             
  394.             self.xmlnode = xmlnode_or_node.docCopyNode(doc, 1)
  395.             parent.addChild(self.xmlnode)
  396.         else:
  397.             self.xmlnode = parent.newChild(None, 'query', None)
  398.             self.ns = self.xmlnode.newNs(DISCO_INFO_NS, None)
  399.             self.xmlnode.setNs(self.ns)
  400.             self.set_node(xmlnode_or_node)
  401.         self.xpath_ctxt = doc.xpathNewContext()
  402.         self.xpath_ctxt.setContextNode(self.xmlnode)
  403.         self.xpath_ctxt.xpathRegisterNs('d', DISCO_INFO_NS)
  404.  
  405.     
  406.     def __del__(self):
  407.         if self.xmlnode:
  408.             self.xmlnode.unlinkNode()
  409.             self.xmlnode.freeNode()
  410.             self.xmlnode = None
  411.         
  412.         if self.xpath_ctxt:
  413.             self.xpath_ctxt.xpathFreeContext()
  414.             self.xpath_ctxt = None
  415.         
  416.  
  417.     
  418.     def get_node(self):
  419.         node = self.xmlnode.prop('node')
  420.         if not node:
  421.             return None
  422.         
  423.         return node.decode('utf-8')
  424.  
  425.     
  426.     def set_node(self, node):
  427.         if node is None:
  428.             if self.xmlnode.hasProp('node'):
  429.                 self.xmlnode.unsetProp('node')
  430.             
  431.             return None
  432.         
  433.         node = unicode(node)
  434.         self.xmlnode.setProp('node', node.encode('utf-8'))
  435.  
  436.     node = property(get_node, set_node)
  437.     
  438.     def get_features(self):
  439.         l = self.xpath_ctxt.xpathEval('d:feature')
  440.         ret = []
  441.         for f in l:
  442.             if f.hasProp('var'):
  443.                 ret.append(f.prop('var').decode('utf-8'))
  444.                 continue
  445.         
  446.         return ret
  447.  
  448.     
  449.     def set_features(self, features):
  450.         for var in self.features:
  451.             self.remove_feature(var)
  452.         
  453.         for var in features:
  454.             self.add_feature(var)
  455.         
  456.  
  457.     features = property(get_features, set_features)
  458.     
  459.     def has_feature(self, var):
  460.         if not var:
  461.             raise ValueError, 'var is None'
  462.         
  463.         if '"' not in var:
  464.             expr = u'd:feature[@var="%s"]' % (var,)
  465.         elif "'" not in var:
  466.             expr = u"d:feature[@var='%s']" % (var,)
  467.         else:
  468.             raise ValueError, 'Invalid feature name'
  469.         l = self.xpath_ctxt.xpathEval(to_utf8(expr))
  470.         if l:
  471.             return True
  472.         else:
  473.             return False
  474.  
  475.     
  476.     def invalidate_features(self):
  477.         warnings.warn('DiscoInfo.invalidate_features() is deprecated and not needed any more.', DeprecationWarning, stacklevel = 1)
  478.  
  479.     
  480.     def add_feature(self, var):
  481.         if self.has_feature(var):
  482.             return None
  483.         
  484.         n = self.xmlnode.newChild(None, 'feature', None)
  485.         n.setProp('var', to_utf8(var))
  486.  
  487.     
  488.     def remove_feature(self, var):
  489.         if not var:
  490.             raise ValueError, 'var is None'
  491.         
  492.         if '"' not in var:
  493.             expr = 'd:feature[@var="%s"]' % (var,)
  494.         elif "'" not in var:
  495.             expr = "d:feature[@var='%s']" % (var,)
  496.         else:
  497.             raise ValueError, 'Invalid feature name'
  498.         l = self.xpath_ctxt.xpathEval(expr)
  499.         if not l:
  500.             return None
  501.         
  502.         for f in l:
  503.             f.unlinkNode()
  504.             f.freeNode()
  505.         
  506.  
  507.     
  508.     def get_identities(self):
  509.         ret = []
  510.         l = self.xpath_ctxt.xpathEval('d:identity')
  511.         if l is not None:
  512.             for i in l:
  513.                 ret.append(DiscoIdentity(self, i))
  514.             
  515.         
  516.         return ret
  517.  
  518.     
  519.     def set_identities(self, identities):
  520.         for identity in self.identities:
  521.             identity.remove()
  522.         
  523.         for identity in identities:
  524.             
  525.             try:
  526.                 self.add_identity(identity.name, identity.category, identity.type)
  527.             continue
  528.             except AttributeError:
  529.                 self.add_identity(*identity)
  530.                 continue
  531.             
  532.  
  533.         
  534.  
  535.     identities = property(get_identities, set_identities)
  536.     
  537.     def identity_is(self, item_category, item_type = None):
  538.         if not item_category:
  539.             raise ValueError, 'bad category'
  540.         
  541.         if not item_type:
  542.             type_expr = u''
  543.         elif '"' not in item_type:
  544.             type_expr = u' and @type="%s"' % (item_type,)
  545.         elif "'" not in type:
  546.             type_expr = u" and @type='%s'" % (item_type,)
  547.         else:
  548.             raise ValueError, 'Invalid type name'
  549.         if '"' not in item_category:
  550.             expr = u'd:identity[@category="%s"%s]' % (item_category, type_expr)
  551.         elif "'" not in item_category:
  552.             expr = u"d:identity[@category='%s'%s]" % (item_category, type_expr)
  553.         else:
  554.             raise ValueError, 'Invalid category name'
  555.         l = self.xpath_ctxt.xpathEval(to_utf8(expr))
  556.         if l:
  557.             return True
  558.         else:
  559.             return False
  560.  
  561.     
  562.     def invalidate_identities(self):
  563.         warnings.warn('DiscoInfo.invalidate_identities() is deprecated and not needed any more.', DeprecationWarning, stacklevel = 1)
  564.  
  565.     
  566.     def add_identity(self, item_name, item_category = None, item_type = None):
  567.         return DiscoIdentity(self, item_name, item_category, item_type)
  568.  
  569.  
  570.  
  571. class DiscoCacheFetcherBase(cache.CacheFetcher):
  572.     stream = None
  573.     disco_class = None
  574.     
  575.     def fetch(self):
  576.         Iq = Iq
  577.         import pyxmpp.iq
  578.         (jid, node) = self.address
  579.         iq = Iq(to_jid = jid, stanza_type = 'get')
  580.         disco = self.disco_class(node)
  581.         iq.add_content(disco.xmlnode)
  582.         self.stream.set_response_handlers(iq, self._DiscoCacheFetcherBase__response, self._DiscoCacheFetcherBase__error, self._DiscoCacheFetcherBase__timeout)
  583.         self.stream.send(iq)
  584.  
  585.     
  586.     def __response(self, stanza):
  587.         
  588.         try:
  589.             d = self.disco_class(stanza.get_query())
  590.             self.got_it(d)
  591.         except ValueError:
  592.             e = None
  593.             self.error(e)
  594.  
  595.  
  596.     
  597.     def __error(self, stanza):
  598.         
  599.         try:
  600.             self.error(stanza.get_error())
  601.         except ProtocolError:
  602.             StanzaErrorNode = StanzaErrorNode
  603.             import pyxmpp.error
  604.             self.error(StanzaErrorNode('undefined-condition'))
  605.  
  606.  
  607.     
  608.     def __timeout(self, stanza):
  609.         pass
  610.  
  611.  
  612.  
  613. def register_disco_cache_fetchers(cache_suite, stream):
  614.     tmp = stream
  615.     
  616.     class DiscoInfoCacheFetcher((DiscoCacheFetcherBase,)):
  617.         stream = tmp
  618.         disco_class = DiscoInfo
  619.  
  620.     
  621.     class DiscoItemsCacheFetcher((DiscoCacheFetcherBase,)):
  622.         stream = tmp
  623.         disco_class = DiscoItems
  624.  
  625.     cache_suite.register_fetcher(DiscoInfo, DiscoInfoCacheFetcher)
  626.     cache_suite.register_fetcher(DiscoItems, DiscoItemsCacheFetcher)
  627.  
  628.